#ifndef _ICMP_H_
#define _ICMP_H_

#include <crt_util.h>
#include "ip.h"

#ifdef    __cplusplus
extern "C"
{
#endif


//----------------------icmp----------------------------------
#define ICMP_ECHOREPLY          0    /* Echo Reply            */
#define ICMP_DEST_UNREACH       3    /* Destination Unreachable    */
#define ICMP_SOURCE_QUENCH      4    /* Source Quench        */
#define ICMP_REDIRECT           5    /* Redirect (change route)    */
#define ICMP_ECHO               8    /* Echo Request            */
#define ICMP_TIME_EXCEEDED      11    /* Time Exceeded        */
#define ICMP_PARAMETERPROB      12    /* Parameter Problem        */
#define ICMP_TIMESTAMP          13    /* Timestamp Request        */
#define ICMP_TIMESTAMPREPLY     14    /* Timestamp Reply        */
#define ICMP_INFO_REQUEST       15    /* Information Request        */
#define ICMP_INFO_REPLY         16    /* Information Reply        */
#define ICMP_ADDRESS            17    /* Address Mask Request        */
#define ICMP_ADDRESSREPLY       18    /* Address Mask Reply        */

// sizeof(icmphdr_t) = 8
typedef struct icmphdr_s {
    uint8_t     type;   // message type
    uint8_t     code;   // type sub-code
    uint16_t    checksum;
    union {
        struct {
            uint16_t    id;
            uint16_t    sequence;
        } echo;
        uint32_t    gateway;
        struct {
            uint16_t    reserved;
            uint16_t    mtu;
        } frag;
    } un;
} icmphdr_t;

typedef struct icmp_s {
    uint8_t     icmp_type;
    uint8_t     icmp_code;
    uint16_t    icmp_cksum;
    union {
        uint8_t ih_pptr;
        struct in_addr ih_gwaddr;
        struct ih_idseq {
            uint16_t icd_id;
            uint16_t icd_seq;
        } ih_idseq;
        uint32_t    ih_void;

        struct ih_pmtu {
            uint16_t ipm_void;
            uint16_t ipm_nextmtu;
        } ih_pmtu;

        struct ih_rtradv {
            uint8_t irt_num_addrs;
            uint8_t irt_wpa;
            uint16_t irt_lifetime;
        } ih_rtradv;
    } icmp_hun;
#define    icmp_pptr    icmp_hun.ih_pptr
#define    icmp_gwaddr    icmp_hun.ih_gwaddr
#define    icmp_id        icmp_hun.ih_idseq.icd_id
#define    icmp_seq    icmp_hun.ih_idseq.icd_seq
#define    icmp_void    icmp_hun.ih_void
#define    icmp_pmvoid    icmp_hun.ih_pmtu.ipm_void
#define    icmp_nextmtu    icmp_hun.ih_pmtu.ipm_nextmtu
#define    icmp_num_addrs    icmp_hun.ih_rtradv.irt_num_addrs
#define    icmp_wpa    icmp_hun.ih_rtradv.irt_wpa
#define    icmp_lifetime    icmp_hun.ih_rtradv.irt_lifetime

    union {
        struct {
            uint32_t its_otime;
            uint32_t its_rtime;
            uint32_t its_ttime;
        } id_ts;
        /*
        struct {
            struct ip idi_ip;
        } id_ip;
        struct icmp_ra_addr id_radv;
        */
        uint32_t id_mask;
        uint8_t  id_data[1];
    } icmp_dun;
#define    icmp_otime    icmp_dun.id_ts.its_otime
#define    icmp_rtime    icmp_dun.id_ts.its_rtime
#define    icmp_ttime    icmp_dun.id_ts.its_ttime
#define    icmp_ip        icmp_dun.id_ip.idi_ip
#define    icmp_radv    icmp_dun.id_radv
#define    icmp_mask    icmp_dun.id_mask
#define    icmp_data    icmp_dun.id_data
} icmp_t;
//#endif

int ping(const char* host, int cnt/* DEFAULT(4)*/);


#ifdef    __cplusplus
}
#endif

#endif // _ICMP_H_
